package com.um.jdy.platform.baofu.contoller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.um.jdy.baofu.api.BaoFuAccountService;
import com.um.jdy.baofu.config.BFConfig;
import com.um.jdy.baofu.config.BaofuPayConfig;
import com.um.jdy.baofu.entity.account.NotifyDataEntity;
import com.um.jdy.baofu.entity.account.ReciveEntity;
import com.um.jdy.baofu.entity.account.RsultBalanceEntity;
import com.um.jdy.baofu.entity.account.TiXianResVo;
import com.um.jdy.baofu.entity.pay.ResultMasterEntity;
import com.um.jdy.baofu.rsa.JHSignatureUtils;
import com.um.jdy.baofu.rsa.RsaCodingUtil;
import com.um.jdy.baofu.utils.RequestParmUtil;
import com.um.jdy.baofu.utils.SecurityUtil;
import com.um.jdy.common.baofu.entity.po.BaofuUser;
import com.um.jdy.common.member.entity.vo.MemberUserVO;
import com.um.jdy.platform.baofu.entity.dto.BaofuUserPageDTO;
import com.um.jdy.platform.baofu.entity.vo.BaofuUserItemVO;
import com.um.jdy.platform.baofu.manager.BaofuManager;
import com.um.jdy.platform.member.entity.dto.MemberPageDTO;
import com.um.jdy.platform.member.manager.MemberUserManager;
import com.um.springboot.starter.annotation.ApiPermission;
import com.um.springboot.starter.annotation.TokenRequired;
import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.orm.controller.BaseController;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.orm.params.PageParams;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;

/**
 * 宝付消息接收类
 */
@Api(tags = "宝付消息接收类")
@RestController
@RequestMapping("/api/v1/cms/baofu/receiveNotice")
@TokenRequired(required = false)
@Validated
@Slf4j
public class BaofuReceiveNoticeController extends BaseController<BaofuManager> {
    @Autowired
    private BFConfig bFConfig;
    @Autowired
    private BaofuPayConfig  baofuPayConfig;
    @Autowired
    private BaoFuAccountService baoFuAccountService;
    @Autowired
    private BaofuManager baofuManager;


    @PostMapping("accountReceiveNotice")
    @ApiOperation(value = "宝付回调", notes = "宝付回调")
    public String accountReceiveNotice(@RequestParam Map<String,Object> Recives)  {
        try {

            if(Recives == null) throw new ServiceException("Parms is Null");
            if(Recives.keySet().size()<=0) throw new ServiceException("No Parms");
            log.info("异步访问入参："+Recives);
            ReciveEntity recive = JSON.parseObject(JSON.toJSONString(Recives),ReciveEntity.class);
            if(recive.getData_content() == null) throw new Exception("datacontent is null");
            String cerpath = ResourceUtils.getFile(bFConfig.getCerpath()).getCanonicalPath();
            String ReslutString = RsaCodingUtil.decryptByPubCerFile(recive.getData_content(), cerpath);

            if(StringUtils.isEmpty(ReslutString))throw new Exception("解密失败");
            ReslutString = SecurityUtil.Base64Decode(ReslutString);
            NotifyDataEntity dataResult = JSON.parseObject(ReslutString,NotifyDataEntity.class);
            log.info("返回数据1："+dataResult.getData());
            JSONObject json = JSON.parseObject(dataResult.getData());
            if(StrUtil.isNotBlank(dataResult.getServiceTp()) && dataResult.getServiceTp().equals("BCT3-1104-001-01")){//开户结果通知
                //修改账户状态，成功或者失败
                manager.accountReceiveProcess(json);
            }else if(StrUtil.isNotBlank(dataResult.getServiceTp()) && dataResult.getServiceTp().equals("BCT3-3104-001-01")){//提现结果通知
                TiXianResVo tiXianResVo = JSONUtil.toBean(dataResult.getData(), TiXianResVo.class);
                System.out.println("提现111111");
                System.out.println(tiXianResVo.toString());
                //state 状态 1成功 0失败 2处理中 3提现退回
                manager.cashoutReceive(tiXianResVo);
            }

            return "OK";
        }catch (Exception ex){
            log.error("开户接收异常：",ex);
            return "OK";
        }
    }

    @PostMapping("payReceiveNotice/{type}/{comId}")
    @ApiOperation(value = "宝付支付回调", notes = "宝付支付回调")
    public String payReceiveNotice(HttpServletRequest request,@PathVariable String type,@PathVariable String comId)  {
        try {
            System.out.println(comId);
            System.out.println(type);
            request.setCharacterEncoding("utf-8");//utf-8编码接收
            RequestParmUtil.getParamLog(request);//打印接收参数

            String  cerpath = baofuPayConfig.getCerpath();//宝付公钥

            Map<String,String> RDateArry = new TreeMap<String,String>();
            Enumeration<String> e = request.getParameterNames();
            while(e.hasMoreElements()) {
                String paraStr = e.nextElement();
                if(paraStr != null){
                    RDateArry.put(paraStr, request.getParameter(paraStr));//接收参数,（使用TreeMap自动排序）
                }
            }
            if(RDateArry.keySet().size()<=0) throw new Exception("参数不存在！");
            ResultMasterEntity rme = JSON.parseObject(JSON.toJSONString(RDateArry),ResultMasterEntity.class);
            log.info("返回参数："+rme);
            if(rme.getSignStr() == null) throw new Exception("缺少验签参数");
            if(rme.getReturnCode().equals("SUCCESS")){
                log.info("11:"+rme.getReturnCode());
                log.info("22:"+rme.getDataContent());
                log.info("33:"+rme.getNotifyType());
                if(JHSignatureUtils.verifySignature(cerpath, rme.getDataContent(), rme.getSignStr())){;
                    JSONObject json = JSON.parseObject(rme.getDataContent());
                    log.info("tradeNo:"+json.getString("tradeNo"));
                    log.info("宝付订单号outTradeNo:"+json.getString("outTradeNo"));
                    log.info("商户订单号outTradeNo:"+json.getString("outTradeNo"));
                    //SUCCESS交易成功，支付成功的订单再次发起支付依然返回支付成功，商户侧需做幂等处理
                    //CLOSED已关闭 通常存在3种情况会关闭订单 1：商户侧发起的订单关闭 2：超出订单有效期还未支付成功的订单，系统自动关闭 3：被风控的订单 已关闭的订单不能再次发起支付
                    //WAIT_PAYING下单成功，等待用户支付中
                    //PAY_ERROR支付失败，同一笔订单号在有效期内可再次发起支付
                    //REFUND支付订单已退款
                    //ABNORMAL 支付异常，返回此状态的支付订单，请稍后发起查询。
                    //退款返回状态
                    log.info("订单状态txnState:"+json.getString("txnState"));
                    log.info("成功金额:succAmt"+json.getString("succAmt"));
                    log.info("支付手续费:feeAmt"+json.getString("feeAmt"));
                    log.info("业务结果:feeAmt"+json.getString("resultCode"));
                    log.info("请求渠道订单号:reqChlNo"+json.getString("reqChlNo"));
                    //月卡支付回调
                    if("monthCard".equals(type)){
                        log.info("月卡支付回调");
                    }else if("chargeEb".equals(type)){
                        ///api/v1/order/charge/eb/wxpay/notify/
                        log.info("Eb支付回调");
                    }else if("chargeEv".equals(type)){
                        ///api/v1/order/charge/ev/wxpay/notify/
                        log.info("Ev支付回调");
                    }else if("chargePb".equals(type)){
                        ///api/v1/order/charge/pb/deposit/%s/notify/
                        log.info("pb支付回调");
                    }else if("wallet".equals(type)){
                        ///api/v1/user/wallet/wxpay/notify/
                        log.info("wallet支付回调");
                    }
                }else{
                    log.error("验签失败："+rme.toString());
                }
            }else {
                log.error("支付回调失败："+rme.toString());
            }

        }catch (Exception ex){
            ex.printStackTrace();
        }
        return "OK";//返回OK与交易状态无关，只表示收到异步通知
    }

    @PostMapping("refundReceiveNotice/{type}/{comId}")
    @ApiOperation(value = "宝付退款回调", notes = "宝付退款回调")
    public String refundReceiveNotice(HttpServletRequest request,@PathVariable String type,@PathVariable String comId)  {
        try {
            System.out.println(comId);
            System.out.println(type);
            request.setCharacterEncoding("utf-8");//utf-8编码接收
            RequestParmUtil.getParamLog(request);//打印接收参数

            String  cerpath = baofuPayConfig.getCerpath();//宝付公钥

            Map<String,String> RDateArry = new TreeMap<String,String>();
            Enumeration<String> e = request.getParameterNames();
            while(e.hasMoreElements()) {
                String paraStr = e.nextElement();
                if(paraStr != null){
                    RDateArry.put(paraStr, request.getParameter(paraStr));//接收参数,（使用TreeMap自动排序）
                }
            }
            if(RDateArry.keySet().size()<=0) throw new Exception("参数不存在！");
            ResultMasterEntity rme = JSON.parseObject(JSON.toJSONString(RDateArry),ResultMasterEntity.class);
            log.info("返回参数："+rme);
            if(rme.getSignStr() == null) throw new Exception("缺少验签参数");
            if(rme.getReturnCode().equals("SUCCESS")){
                log.info("11:"+rme.getReturnCode());
                log.info("22:"+rme.getDataContent());
                log.info("33:"+rme.getNotifyType());
                if(JHSignatureUtils.verifySignature(cerpath, rme.getDataContent(), rme.getSignStr())){
                    JSONObject json = JSON.parseObject(rme.getDataContent());
                    String outTradeNo = json.getString("outTradeNo");
                    String tradeNo = json.getString("tradeNo");
                    String finishTime =  json.getString("finishTime");
                    log.info("宝付订单号tradeNo:"+tradeNo);
                    log.info("商户订单号outTradeNo:"+outTradeNo);
                    log.info("支付完成时间finishTime:"+finishTime);
                    //SUCCESS交易成功，支付成功的订单再次发起支付依然返回支付成功，商户侧需做幂等处理
                    //CLOSED已关闭 通常存在3种情况会关闭订单 1：商户侧发起的订单关闭 2：超出订单有效期还未支付成功的订单，系统自动关闭 3：被风控的订单 已关闭的订单不能再次发起支付
                    //WAIT_PAYING下单成功，等待用户支付中
                    //PAY_ERROR支付失败，同一笔订单号在有效期内可再次发起支付
                    //REFUND支付订单已退款
                    //ABNORMAL 支付异常，返回此状态的支付订单，请稍后发起查询。
                    //退款返回状态
                    log.info("订单状态txnState:"+json.getString("txnState"));
                    log.info("成功金额:succAmt"+json.getString("succAmt"));
                    log.info("支付手续费:feeAmt"+json.getString("feeAmt"));
                    log.info("业务结果:feeAmt"+json.getString("resultCode"));
                    log.info("请求渠道订单号:reqChlNo"+json.getString("reqChlNo"));
                    //月卡支付回调
                    if("monthCard".equals(type)){
                        log.info("月卡支付回调");
                       // monthCardManager.BaofuWxPayNotify(outTradeNo,finishTime,comId);
                    }else if("chargeEb".equals(type)){
                        ///api/v1/order/charge/eb/wxpay/notify/
                        log.info("Eb支付回调");
                       // ebOrderManager.baofuWxPayNotify(outTradeNo,tradeNo,finishTime);
                    }else if("chargeEv".equals(type)){
                        ///api/v1/order/charge/ev/wxpay/notify/
                        log.info("Ev支付回调");
                       // evOrderManager.baofuWxPayNotify(outTradeNo,tradeNo,finishTime,comId);
                    }else if("chargePb".equals(type)){
                        ///api/v1/order/charge/pb/deposit/%s/notify/
                        log.info("pb支付回调");
                       // pbOrderManager.baofuDepositWxPayNotify(outTradeNo,finishTime,comId);
                    }else if("wallet".equals(type)){
                        ///api/v1/user/wallet/wxpay/notify/
                        log.info("wallet支付回调");
                       // walletManager.baofuWxPayNotify(outTradeNo,finishTime,comId);
                    }
                }else{
                    log.error("验签失败："+rme.toString());
                }
            }else {
                log.error("支付回调失败："+rme.toString());
            }

        }catch (Exception ex){
            ex.printStackTrace();
        }
        return "OK";//返回OK与交易状态无关，只表示收到异步通知
    }

    @ApiOperation("查询宝付余额信息")
    @GetMapping("getbBaoUser")
    public Response<RsultBalanceEntity> getbBaoUser(String id){
        RsultBalanceEntity balanceEntity = baoFuAccountService.BCT3_2001_001_01(id,1);
        if(balanceEntity.getRetCode() != 1){
            balanceEntity = baoFuAccountService.BCT3_2001_001_01(id,2);
        }
        return Response.success(balanceEntity);
    }

    @ApiOperation("执行提现定时任务")
    @GetMapping("execute")
    public String execute(){
        baofuManager.schEduledCashout();
        return "ok";
    }
}
